package com.fjh.springboot_01.controller;

import com.fjh.springboot_01.pojo.Result;
import com.fjh.springboot_01.pojo.User;
import com.fjh.springboot_01.service.UserService;
import com.fjh.springboot_01.utils.EmailUtil;
import com.fjh.springboot_01.utils.JwtUtil;
import com.fjh.springboot_01.utils.Md5Util;
import com.fjh.springboot_01.utils.ThreadLocalUtil;
import jakarta.annotation.Resource;
import jakarta.validation.constraints.Pattern;
import org.hibernate.validator.constraints.URL;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.util.StringUtils;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;

@RestController
@RequestMapping("/user")
@Validated
public class UserController {
    @Autowired
    private UserService userService;

    @Resource
    private StringRedisTemplate stringRedisTemplate;

    @Autowired
    private EmailUtil emailUtil;

    @Autowired
    private JwtUtil jwtUtil;

    /**
     * 发送验证码到网易邮箱
     */
    @PostMapping("/sendVerificationCode")
    public Result sendVerificationCode(@RequestBody Map<String, String> request) {
        String email = request.get("email");

        if (!StringUtils.hasLength(email)) {
            return Result.error("邮箱不能为空");
        }

        // 生成 4 位验证码
        String code = emailUtil.generateCode();

        // 存入 Redis，5 分钟过期
        stringRedisTemplate.opsForValue().set(email, code, 5, TimeUnit.MINUTES);

        // 发送验证码邮件
        boolean emailSent = emailUtil.sendVerificationCode(email, code);

        if (emailSent) {
            return Result.success("验证码已发送，请查收");
        } else {
            return Result.error("验证码发送失败，请稍后重试");
        }
    }

    /**
     * 用户注册
     */
    @PostMapping("/register")
    public Result register(@RequestBody Map<String, String> request) {
        String username = request.get("username");
        String password = request.get("password");
        String email = request.get("email");
        String verificationCode = request.get("verificationCode");
        Integer role = Integer.parseInt(request.get("role")); // 0-学生，1-教师，2-管理员

        if (!StringUtils.hasLength(username) || !StringUtils.hasLength(password) || 
            !StringUtils.hasLength(email) || !StringUtils.hasLength(verificationCode)) {
            return Result.error("所有字段均不能为空");
        }
        // 检查用户名是否存在
        User existingUser = userService.findByUserName(username);
        if (existingUser != null) {
            return Result.error("用户名已被占用");
        }
        // 验证验证码
        String cachedCode = stringRedisTemplate.opsForValue().get(email);
        if (cachedCode == null || !cachedCode.equals(verificationCode)) {
            return Result.error("验证码错误或已过期");
        }
        // 注册用户
        userService.register(username, password, email, role);
        // 删除 Redis 中的验证码
        stringRedisTemplate.delete(email);
        return Result.success("注册成功" + (role == 1 ? "，请等待管理员审核" : ""));
    }

    @PostMapping("/login")
    public Result<String> login(@Pattern(regexp = "^\\S{5,16}$") String username,
                              @Pattern(regexp = "^\\S{5,16}$") String password) {
        try {
            // 检查用户是否存在
            User loginUser = userService.findByUserName(username);
            if (loginUser == null) {
                return Result.error("用户不存在，请检查用户名是否正确");
            }
            
            // 判断用户是否被禁用
            if (loginUser.getStatus() != null && loginUser.getStatus() == 0) {
                return Result.error("账号已被禁用，请联系管理员");
            }

            // 判断密码准确性
            if (Md5Util.getMD5String(password).equals(loginUser.getPassword())) {
                // 如果是教师，检查审核状态
                if (loginUser.getRole() == 1) {
                    if (loginUser.getTeacherStatus() == null || loginUser.getTeacherStatus() == 0) {
                        // 创建一个临时的学生身份token
                        Map<String,Object> claims = new HashMap<>();
                        claims.put("id", loginUser.getId());
                        claims.put("username", loginUser.getUsername());
                        claims.put("role", 0); // 临时设置为学生角色
                        claims.put("teacherStatus", loginUser.getTeacherStatus());
                        String token = jwtUtil.genToken(claims);
                        
                        // token存储redis
                        ValueOperations<String,String> operations = stringRedisTemplate.opsForValue();
                        operations.set(token, token, 1, TimeUnit.HOURS);
                        return Result.success(token);
                    } else if (loginUser.getTeacherStatus() == 2) {
                        return Result.error("您的教师身份申请已被拒绝");
                    }
                }

                Map<String,Object> claims = new HashMap<>();
                claims.put("id", loginUser.getId());
                claims.put("username", loginUser.getUsername());
                claims.put("role", loginUser.getRole());
                claims.put("teacherStatus", loginUser.getTeacherStatus());
                String token = jwtUtil.genToken(claims);
                
                // token存储redis
                ValueOperations<String,String> operations = stringRedisTemplate.opsForValue();
                operations.set(token, token, 1, TimeUnit.HOURS);
                return Result.success(token);
            }
            return Result.error("密码错误，请重新输入");
        } catch (Exception e) {
            e.printStackTrace();
            return Result.error("登录失败：" + e.getMessage());
        }
    }

    @GetMapping("/userInfo")
    public Result<User> userInfo(){
        Map<String, Object> map= ThreadLocalUtil.get();
        String username=(String) map.get("username");
        User user=userService.findByUserName(username);
        return Result.success(user);
    }

    @GetMapping("/userInfo/{username}")
    public Result<User> getUserInfoByUsername(@PathVariable("username") String username) {
        // 根据传入的用户名查询用户信息
        User user = userService.findByUserName(username);
        if (user == null) {
            return Result.error("用户不存在");
        }
        return Result.success(user);
    }

    @PutMapping("/update")
    public Result update(@RequestBody @Validated User user){
        userService.update(user);
        return Result.success();
    }
    @PatchMapping ("/updateAvatar")
    public Result updateAvatar(@RequestParam @URL String avatarUrl){
        userService.updateAvatar(avatarUrl);
        return Result.success();
    }

    @PatchMapping("/updatePwd")
    public Result updatePwd(@RequestBody Map<String,String> params,@RequestHeader("Authorization") String token){
        String oldPwd=params.get("old_pwd");
        String newPwd=params.get("new_pwd");
        String rePwd = params.get("re_pwd");

        if (!StringUtils.hasLength(oldPwd) || !StringUtils.hasLength(newPwd) || !StringUtils.hasLength(rePwd)) {
            return Result.error("缺少必要的参数");
        }
        //原密码是否正确
        //调用userService根据用户名拿到原密码,再和old_pwd比对
        Map<String,Object> map = ThreadLocalUtil.get();
        String username = (String) map.get("username");
        User loginUser = userService.findByUserName(username);
        if (!loginUser.getPassword().equals(Md5Util.getMD5String(oldPwd))){
            return Result.error("原密码填写不正确");
        }

        //newPwd和rePwd是否一样
        if (!rePwd.equals(newPwd)){
            return Result.error("两次填写的新密码不一样");
        }
        //2.调用service完成密码更新
        userService.updatePwd(newPwd);
        //        删除token
        ValueOperations<String,String> operations=stringRedisTemplate.opsForValue();
        operations.getOperations().delete(token);
        return Result.success();
    }

    // 管理员获取待审核的教师列表
    @GetMapping("/pending-teachers")
    public Result<List<User>> getPendingTeachers() {
        // 验证当前用户是否是管理员
        Map<String, Object> map = ThreadLocalUtil.get();
        Integer role = (Integer) map.get("role");
        if (role != 2) {
            return Result.error("无权限访问");
        }
        return Result.success(userService.getPendingTeachers());
    }

    // 管理员处理教师审核
    @PostMapping("/handle-teacher-approval")
    public Result handleTeacherApproval(@RequestBody Map<String, Integer> request) {
        // 验证当前用户是否是管理员
        Map<String, Object> map = ThreadLocalUtil.get();
        Integer role = (Integer) map.get("role");
        if (role != 2) {
            return Result.error("无权限访问");
        }

        Integer userId = request.get("userId");
        Integer status = request.get("status"); // 1-通过，2-拒绝

        if (userId == null || status == null || (status != 1 && status != 2)) {
            return Result.error("参数错误");
        }

        userService.handleTeacherApproval(userId, status);
        
        // 如果是审核通过，清除该用户的所有token，强制重新登录
        if (status == 1) {
            // 获取用户信息
            User user = userService.findById(userId);
            if (user != null) {
                // 生成一个临时token用于删除
                Map<String, Object> claims = new HashMap<>();
                claims.put("id", user.getId());
                claims.put("username", user.getUsername());
                String tempToken = jwtUtil.genToken(claims);
                // 删除token
                stringRedisTemplate.delete(tempToken);
            }
        }
        
        return Result.success(status == 1 ? "已通过审核，用户需要重新登录" : "已拒绝申请");
    }

    // 获取所有用户或特定角色的用户列表
    @GetMapping({"/users-by-role", "/users-by-role/{role}"})
    public Result<List<User>> getUsersByRole(@PathVariable(required = false) String role) {
        // 验证当前用户是否是管理员
        Map<String, Object> map = ThreadLocalUtil.get();
        Integer currentRole = (Integer) map.get("role");
        if (currentRole != 2) {
            return Result.error("无权限访问");
        }
        
        try {
            Integer roleInt = null;
            if (role != null && !role.equals("all")) {
                try {
                    roleInt = Integer.parseInt(role);
                } catch (NumberFormatException e) {
                    return Result.error("角色参数格式错误");
                }
            }
            List<User> users = userService.getUsersByRole(roleInt);
            return Result.success(users);
        } catch (Exception e) {
            return Result.error("获取用户列表失败");
        }
    }

    // 更新用户状态
    @PatchMapping("/update-status")
    public Result updateUserStatus(@RequestBody Map<String, Integer> request) {
        // 验证当前用户是否是管理员
        Map<String, Object> map = ThreadLocalUtil.get();
        Integer currentRole = (Integer) map.get("role");
        if (currentRole != 2) {
            return Result.error("无权限访问");
        }

        Integer userId = request.get("userId");
        Integer status = request.get("status");

        if (userId == null || status == null) {
            return Result.error("参数错误");
        }

        try {
            userService.updateUserStatus(userId, status);
            return Result.success("更新用户状态成功");
        } catch (Exception e) {
            return Result.error("更新用户状态失败");
        }
    }

    // 删除用户
    @DeleteMapping("/{userId}")
    public Result deleteUser(@PathVariable Integer userId) {
        // 验证当前用户是否是管理员
        Map<String, Object> map = ThreadLocalUtil.get();
        Integer currentRole = (Integer) map.get("role");
        if (currentRole != 2) {
            return Result.error("无权限访问");
        }

        try {
            userService.deleteUser(userId);
            return Result.success("删除用户成功");
        } catch (Exception e) {
            return Result.error("删除用户失败");
        }
    }
    
    /**
     * 已登录用户重置密码
     */
    @PatchMapping("/resetPassword")
    public Result resetPassword(@RequestBody Map<String, String> params, @RequestHeader("Authorization") String token) {
        String oldPwd = params.get("old_pwd");
        String newPwd = params.get("new_pwd");
        String rePwd = params.get("re_pwd");

        if (!StringUtils.hasLength(oldPwd) || !StringUtils.hasLength(newPwd) || !StringUtils.hasLength(rePwd)) {
            return Result.error("缺少必要的参数");
        }
        
        // 原密码是否正确
        Map<String, Object> map = ThreadLocalUtil.get();
        String username = (String) map.get("username");
        User loginUser = userService.findByUserName(username);
        if (!loginUser.getPassword().equals(Md5Util.getMD5String(oldPwd))) {
            return Result.error("原密码填写不正确");
        }

        // 新密码和确认密码是否一样
        if (!rePwd.equals(newPwd)) {
            return Result.error("两次填写的新密码不一样");
        }
        
        // 调用service完成密码更新
        userService.updatePwd(newPwd);
        
        // 删除token，强制重新登录
        ValueOperations<String, String> operations = stringRedisTemplate.opsForValue();
        operations.getOperations().delete(token);
        
        return Result.success("密码修改成功，请重新登录");
    }
    
    /**
     * 忘记密码 - 通过邮箱验证码重置
     */
    @PostMapping("/forgotPassword")
    public Result forgotPassword(@RequestBody Map<String, String> request) {
        String username = request.get("username");
        String email = request.get("email");
        String verificationCode = request.get("verificationCode");
        String newPassword = request.get("newPassword");
        String confirmPassword = request.get("confirmPassword");
        
        if (!StringUtils.hasLength(username) || !StringUtils.hasLength(email) || 
            !StringUtils.hasLength(verificationCode) || !StringUtils.hasLength(newPassword) || 
            !StringUtils.hasLength(confirmPassword)) {
            return Result.error("缺少必要的参数");
        }
        
        // 检查用户名是否存在
        User user = userService.findByUserName(username);
        if (user == null) {
            return Result.error("用户不存在");
        }
        
        // 验证邮箱是否匹配
        if (!user.getEmail().equals(email)) {
            return Result.error("用户名与邮箱不匹配");
        }
        
        // 验证验证码
        String cachedCode = stringRedisTemplate.opsForValue().get(email);
        if (cachedCode == null || !cachedCode.equals(verificationCode)) {
            return Result.error("验证码错误或已过期");
        }
        
        // 检查两次密码是否一致
        if (!newPassword.equals(confirmPassword)) {
            return Result.error("两次输入密码不一致");
        }
        
        // 更新密码
        userService.resetPassword(username, newPassword);
        
        // 删除Redis中的验证码
        stringRedisTemplate.delete(email);
        
        // 清除该用户所有token
        // 这里可以根据需要添加清除token的代码
        
        return Result.success("密码重置成功，请使用新密码登录");
    }
}
